#include "postbonddataanalysis.h"

PostBondDataAnalysis::PostBondDataAnalysis(QObject *parent)
{
    rangeCount = (MaxOffset - MinOffset) / RangeSize + 1;
    everyXOffsetRangeCount = new int[rangeCount];
    everyYOffsetRangeCount = new int[rangeCount];
    for (int i = 0; i < rangeCount; i++)
    {
        everyXOffsetRangeCount[i] = 0;
        everyYOffsetRangeCount[i] = 0;
    }
}

PostBondDataAnalysis::~PostBondDataAnalysis()
{
    delete everyXOffsetRangeCount;
    delete everyYOffsetRangeCount;
}

void PostBondDataAnalysis::appendData(PrOffset &prOffset)
{
    QMutexLocker tmpLocker(&locker);
    bool reachMaxData = (postBondOffsets.count() == 100);
    if (postBondOffsets.count() == 100)
    {
        PrOffset firstOffset = postBondOffsets.takeAt(0);
        int xOffsetRangeIndex = getOffsetRangeIndex(firstOffset.X);
        int yOffsetRangeIndex = getOffsetRangeIndex(firstOffset.Y);
        everyXOffsetRangeCount[xOffsetRangeIndex]--;
        everyYOffsetRangeCount[yOffsetRangeIndex]--;
        notifyDataDistributionChanged(xOffsetRangeIndex, yOffsetRangeIndex);
    }
    postBondOffsets.append(prOffset);
    emit newData(prOffset.X, prOffset.Y);
    int xOffsetRangeIndex = getOffsetRangeIndex(prOffset.X);
    int yOffsetRangeIndex = getOffsetRangeIndex(prOffset.Y);
    everyXOffsetRangeCount[xOffsetRangeIndex]++;
    everyYOffsetRangeCount[yOffsetRangeIndex]++;
    if (reachMaxData)
    {
        notifyDataDistributionChanged(xOffsetRangeIndex, yOffsetRangeIndex);
    }
    else
    {
        QVariantList yAxisXOffsetsDistribution;
        QVariantList yAxisYOffsetsDistribution;
        QVariantList xAxis;
        double tmp_maxOffsetRatio = 0;
        for (int i = 0; i < rangeCount; i++)
        {
            double xOffsetRatio = everyXOffsetRangeCount[i] * 100.0 / postBondOffsets.count();
            double yOffsetRatio = everyYOffsetRangeCount[i] * 100.0 / postBondOffsets.count();
            if (xOffsetRatio > tmp_maxOffsetRatio)
            {
                tmp_maxOffsetRatio = xOffsetRatio;
            }
            if (yOffsetRatio > tmp_maxOffsetRatio)
            {
                tmp_maxOffsetRatio = yOffsetRatio;
            }
            xAxis.append(i * RangeSize + MinOffset);
            yAxisXOffsetsDistribution.append(xOffsetRatio);
            yAxisYOffsetsDistribution.append(yOffsetRatio);
        }
        emit newDataDistribution(xAxis, yAxisXOffsetsDistribution, yAxisYOffsetsDistribution, tmp_maxOffsetRatio);
    }
}

void PostBondDataAnalysis::clearData()
{
    QMutexLocker tmpLocker(&locker);
    postBondOffsets.clear();
    for (int i = 0; i < rangeCount; i++)
    {
        everyXOffsetRangeCount[i] = 0;
        everyYOffsetRangeCount[i] = 0;
    }
}

int PostBondDataAnalysis::getOffsetRangeIndex(double &offset)
{
    int validOffset = round(offset);
    if (validOffset < MinOffset)
    {
        validOffset = MinOffset;
    }
    else if (validOffset > MaxOffset)
    {
        validOffset = MaxOffset;
    }
    return (validOffset - MinOffset) / RangeSize;
}

void PostBondDataAnalysis::notifyDataDistributionChanged(int xOffsetRangeIndex, int yOffsetRangeIndex)
{
    double xOffsetRatio = everyXOffsetRangeCount[xOffsetRangeIndex];
    if (xOffsetRatio > maxOffsetRatio)
    {
        maxOffsetRatio = xOffsetRatio;
    }
    double yOffsetRatio = everyYOffsetRangeCount[yOffsetRangeIndex];
    if (yOffsetRatio > maxOffsetRatio)
    {
        maxOffsetRatio = yOffsetRatio;
    }
    emit dataDistributionChanged(xOffsetRangeIndex, xOffsetRangeIndex * RangeSize + MinOffset, xOffsetRatio,
                                 yOffsetRangeIndex, yOffsetRangeIndex * RangeSize + MinOffset, yOffsetRatio,
                                 maxOffsetRatio);
}

void PostBondDataAnalysis::pushData()
{
    PrOffset offset;
    offset.X = rand() % 40 - 15;
    offset.Y = rand() % 40 - 25;
    appendData(offset);
}

void PostBondDataAnalysis::pushDatas(int count)
{
    if (isPushingDatas)
    {
        return;
    }
    isPushingDatas = true;
    for (int i = 0; i < count; i++)
    {
        if (!isPushingDatas)
        {
            return;
        }
        pushData();
        QThread::msleep(50);
    }
    isPushingDatas = false;
}

void PostBondDataAnalysis::stopPushDatas()
{
    isPushingDatas = false;
}
